use std::{fs, os};
use std::path::Path;

use clap::{Arg, ArgAction, ArgMatches, Command};

use crate::environment::environment;
use crate::util::util::system::lockpath;

pub const NAME: &'static str = "lin";

pub fn new() -> Command {
    let mut command = Command::new(NAME).about("链接器，支持将指定命令链接到系统环境");
    command = command.arg(Arg::new("name").required(true).help("需要链接的命令名称"));
    command = command.arg(Arg::new("remove").action(ArgAction::SetTrue).short('r').long("remove").help("移除命令的链接"));
    command = command.arg(Arg::new("force").action(ArgAction::SetTrue).short('f').long("force").help("强制覆盖"));

    command
}

pub fn action(args: &ArgMatches) {
    let name = args.get_one::<String>("name").unwrap();
    let path = lockpath::lock_path(name.as_str(), environment::resolve_paths().as_ref());
    if path.is_err() {
        println!("查找命令失败: {}", path.unwrap_err().to_string());

        return;
    }

    let path = path.unwrap();
    if path.is_none() {
        println!("未找到命令: {}", name);

        return;
    }

    let path = path.unwrap();
    let target = Path::new("/").join("opt").join("dem").join("bin").join(name);

    if target.exists() {
        if args.get_flag("remove") || args.get_flag("force") {
            let result = fs::remove_file(target.clone());
            if result.is_err() {
                println!("移除目标[{}]失败: {}", target.to_str().unwrap(), result.unwrap_err().to_string());

                return;
            }

            if args.get_flag("remove") {
                return;
            }
        }

        if !args.get_flag("force") {
            println!("目标位置[{}]已存在，若要覆盖链接请指定--force选项", target.to_str().unwrap());

            return;
        }
    }


    #[cfg(any(target_os = "macos", target_os = "linux"))]
    {
        let result = os::unix::fs::symlink(Path::new(path.as_str()), target.clone());
        if result.is_err() {
            println!("链接[{}]->[{}]失败: {}", path, target.to_str().unwrap(), result.unwrap_err().to_string());

            return;
        }
    }
}